Skip to main content
Glama

Gitlab Create MR Tool

Generate new Merge Requests in GitLab, assign users, and add reviewers for streamlined code collaboration. Simplify project management by specifying branches, titles, and labels.

Instructions

创建新的 Merge Request,支持指派 assignee 和 reviewers。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
assigneeIdNo指派的用户 ID
descriptionNo描述
fieldsNo需要返回的字段路径数组
labelsNo标签数组
projectIdYes项目 ID
reviewerIdsNoReviewer 用户 ID 列表
sourceBranchYes源分支
targetBranchYes目标分支
titleYes标题

Implementation Reference

  • Main tool handler: the `execute` method that performs project/user resolution, GitLab API POST to create merge request, response filtering, and error handling.
    async execute(args: unknown, context: Context<Record<string, unknown> | undefined>) { const typedArgs = args as { projectId: string | number; sourceBranch: string; targetBranch: string; title: string; description?: string; assigneeId?: string | number; reviewerIds?: (string | number)[]; labels?: string[]; fields?: string[]; }; const { projectId: projectIdOrName, sourceBranch, targetBranch, title, description, assigneeId: assigneeIdOrName, reviewerIds: reviewerIdsOrNames, labels, fields } = typedArgs; try { const client = createGitlabClientFromContext(context); // 解析项目 ID const resolvedProjectId = await client.resolveProjectId(projectIdOrName); if (!resolvedProjectId) { throw new Error(`无法解析项目 ID 或名称:${projectIdOrName}`); } const endpoint = `/projects/${encodeURIComponent(String(resolvedProjectId))}/merge_requests`; let resolvedAssigneeId: number | undefined = undefined; if (assigneeIdOrName !== undefined) { const resolved = await client.resolveUserId(assigneeIdOrName); if (resolved) { resolvedAssigneeId = resolved; } else { // 选择性失败:可以记录警告并继续,或者抛出错误 console.warn(`无法解析指派人 ID 或用户名:${assigneeIdOrName},将忽略此参数`); // throw new Error(`无法解析指派人 ID 或用户名:${assigneeIdOrName}`); } } let resolvedReviewerIds: number[] = []; if (reviewerIdsOrNames && reviewerIdsOrNames.length > 0) { const reviewerPromises = reviewerIdsOrNames.map(idOrName => client.resolveUserId(idOrName)); const results = await Promise.all(reviewerPromises); resolvedReviewerIds = results.filter((id): id is number => { if (id === null) { // 找到原始输入用于警告 const originalInput = reviewerIdsOrNames[results.indexOf(id)]; console.warn(`无法解析审阅人 ID 或用户名:${originalInput},将忽略此审阅人`); } return id !== null; }); } const createData: Record<string, any> = { source_branch: sourceBranch, target_branch: targetBranch, title, }; if (description !== undefined) createData.description = description; if (resolvedAssigneeId !== undefined) createData.assignee_id = resolvedAssigneeId; if (resolvedReviewerIds.length > 0) createData.reviewer_ids = resolvedReviewerIds; if (labels !== undefined) createData.labels = labels.join(","); const response = await client.apiRequest(endpoint, "POST", undefined, createData); if (!client.isValidResponse(response)) { throw new Error(`GitLab API error: ${response?.message || 'Unknown error'}`); } if (fields) { const filteredResponse = filterResponseFields(response, fields); return { content: [{ type: "text", text: JSON.stringify(filteredResponse) }] } as ContentResult; } return { content: [{ type: "text", text: JSON.stringify(response) }] } as ContentResult; } catch (error: any) { return { content: [ { type: "text", text: `GitLab MCP 工具调用异常:${error?.message || String(error)}` } ], isError: true }; } }
  • Zod schema defining the tool's input parameters including projectId, branches, title, assignees, reviewers, etc.
    parameters: z.object({ projectId: z.union([z.string(), z.number()]).describe("项目 ID 或名称"), sourceBranch: z.string().describe("源分支"), targetBranch: z.string().describe("目标分支"), title: z.string().describe("标题"), description: z.string().optional().describe("描述"), assigneeId: z.union([z.string(), z.number()]).optional().describe("指派的用户 ID 或用户名"), reviewerIds: z.array(z.union([z.string(), z.number()])).optional().describe("Reviewer 用户 ID 或用户名列表"), labels: z.array(z.string()).optional().describe("标签数组"), fields: z.array(z.string()).optional().describe("需要返回的字段路径数组"), }),
  • Inclusion of `GitlabCreateMRTool` in the `fastmcpTools` array, which is iterated over to register all GitLab tools with the MCP server.
    const fastmcpTools = [ GitlabAcceptMRTool, GitlabCreateMRCommentTool, GitlabCreateMRTool, GitlabGetUserTasksTool, GitlabRawApiTool, GitlabSearchProjectDetailsTool, GitlabSearchUserProjectsTool, GitlabUpdateMRTool, ];
  • The registration loop in `registerGitLabToolsForFastMCP` that conditionally adds each tool to the FastMCP server using `server.addTool(tool)`. A similar process exists for MCP SDK registration.
    fastmcpTools.forEach(tool => { const standardizedName = toolNameMapping[tool.name as keyof typeof toolNameMapping]; if (shouldRegisterTool(standardizedName as GitLabToolName, options.toolFilter)) { // GitLabTool is now fully compatible with FastMCP's base type, can be registered directly server.addTool(tool); } });
  • Mapping of the tool's display name to the standardized `GitLabToolName` enum value 'Gitlab_Create_MR_Tool' for type safety and filtering.
    [GitlabCreateMRTool.name]: "Gitlab_Create_MR_Tool",

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ZephyrDeng/mcp-server-gitlab'

If you have feedback or need assistance with the MCP directory API, please join our Discord server